package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.ruoyi.business.domain.CarMaintenanceInfo;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.HistoricActivity;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.CarPackageAuditMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by lanxw
 */
@Service
public class CarPackageAuditServiceImpl implements ICarPackageAuditService {
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private IProcessService processService;
    @Autowired
    private IServiceItemService serviceItemService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public void insertCarPackageAudit(CarPackageAudit carPackageAudit) {
        carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    @Override
    public void updateCarPackageAudit(CarPackageAudit carPackageAudit) {
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit) {
        List<CarPackageAudit> carMaintenanceInfos = carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
        for(CarPackageAudit audit:carMaintenanceInfos){
            audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));//反序列化
            //根据数据中的流程实例id查询任务名称
            Task task = processService.getTaskByInstanceId(audit.getInstanceId());
            if(task!=null){ //任务没有结束
                audit.setTaskId(task.getId());
                audit.setTaskName(task.getName());
            }else{
                audit.setTaskName("已结束");
            }
        }
        return carMaintenanceInfos;
    }
    //撤销审核
    @Override
    @Transactional
    public void cancelApply(String instanceId) {
        //根据流程实例ID => 流程实例对象 =>获取业务key=>审核对象，更新状态为撤销状态    把快照表的信息(状态修改为撤销,审核人设置为空)
        CarPackageAudit carPackageAudit = carPackageAuditMapper.getCarPackageAudit(processService.getProcessInstanceById(instanceId).getBusinessKey());
        carPackageAudit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAudit.setAuditors("");
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);//更新到数据库的表
        //获取服务项,更新审核状态为初始化      目前状态  审核中
        ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(),ServiceItem.class);
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);//状态修改为初始化0
        serviceItemService.updateServiceItemNoCondition(serviceItem);//修改进去数据库的表
        processService.deleteProcessInstance(instanceId,"用户撤销");   //删除流程实例
    }

    @Override
    public CarPackageAudit getCarPackageAudit(String id) {
        return carPackageAuditMapper.getCarPackageAudit(id);
    }

    /**
     * 查询待办任务集合方法
     */
    @Override
    public List<CarPackageAudit> findTodoList(CarPackageAudit carPackageAudit) {
        //1.查询当前登录用户关于审核的所有的 我的待办列表
        long count = processService.selectTodoTaskCount(CarPackageAudit.DEFINITION_KEY, ShiroUtils.getUserId().toString());
        if(count>0){
            //模仿框架底层写即可  BaseController类的startPage
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            //自己写的方法
            List<Task> taskList = processService
                    .selectTodoTaskList(CarPackageAudit.DEFINITION_KEY,
                            ShiroUtils.getUserId().toString(),
                            (pageNum-1)*pageSize,//当前页-1 3=0 3
                            pageSize);//3)
            //3.遍历待办任务,查询对应的CarPackAgeAudit
            List<CarPackageAudit> resultList = new ArrayList<>();
            for (Task task : taskList) {
                //ProcessInstanceId => processInstance => businessKey即是t_car_package_audit的id
                CarPackageAudit audit = carPackageAuditMapper.getCarPackageAudit
                        (processService.getProcessInstanceById(task.getProcessInstanceId()).getBusinessKey());
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));//解析
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
                resultList.add(audit);
            }
            Page<CarPackageAudit> list = new Page<>();  //将数据封装成Page对象返回,里面包含总数,分页条数,页码
            list.setTotal(count);
            list.setPageNum(pageNum);
            list.setPageSize(pageSize);
            list.addAll(resultList);
            return list;
        }else{
            return Collections.emptyList();//如果总数为0,返回空集合回去
        }
    }

    @Override
    @Transactional
    public void complete(String taskId, String auditStatus, String comment) {
        boolean auditStatusBoolean = BooleanUtils.toBoolean(auditStatus);//工具类
        String commentStr = auditStatusBoolean?"【同意】":"【拒绝】";
        if(StringUtils.isNotEmpty(comment)){
            commentStr +=comment;
        }
        //1.根据任务Id查询任务对象
        Task task = processService.getTaskByTaskId(taskId);
        //这步需要放在前面
        ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
        //3.给任务添加批注,设置流程变量,领取任务,完成任务
        processService.claimAndComplateTask(task,ShiroUtils.getUserId().toString(),auditStatusBoolean,commentStr);
        //4.完成任务后查询流程实例的下一个任务.
        Task nextTask = processService.getTaskByInstanceId(task.getProcessInstanceId());
        CarPackageAudit audit = carPackageAuditMapper.getCarPackageAudit(instance.getBusinessKey());
        //5.判断流程是否已经结束
        if(nextTask!=null){
            //5.1任务没有结束
            //需要指定下一个任务的候选人
            List<String> auditors = new ArrayList<>();
            //判断审核通过和是审核拒绝
            if(auditStatusBoolean){
                String taskDefinitionKey = nextTask.getTaskDefinitionKey();
                List<SysUser> auditorIdList = definitionNodeService.queryAuditorsByTaskDefinitionKey(taskDefinitionKey);
                for(SysUser auditor:auditorIdList){
                    processService.addCandidateUser(nextTask.getId(),auditor.getUserId().toString());
                    auditors.add(auditor.getUserName());
                }
            }else{
                String userId = audit.getCreateBy();
                auditors.add(audit.getCreateByName());
                processService.addCandidateUser(nextTask.getId(),userId);
                audit.setStatus(CarPackageAudit.STATUS_REJECT);
            }
            audit.setAuditors(JSON.toJSONString(auditors));
            carPackageAuditMapper.updateCarPackageAudit(audit);
        }else{
            //5.2 任务结束
            //修改CarPackageAudit的状态,审核人字段设置为空
            audit.setAuditors("");
            audit.setStatus(CarPackageAudit.STATUS_PASS);
            carPackageAuditMapper.updateCarPackageAudit(audit);
            //修改养修明细项审核状态
            ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class);
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
            serviceItemService.updateServiceItemNoCondition(serviceItem);
        }
    }

    @Override
    @Transactional
    public void updateServiceItem(String carPackageAuditId, ServiceItem serviceItem) {
        serviceItemService.updateServiceItemNoCondition(serviceItem);
        CarPackageAudit carPackageAudit = carPackageAuditMapper.getCarPackageAudit(carPackageAuditId);
        carPackageAudit.setServiceItemInfo(JSON.toJSONString(serviceItem));
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    @Override
    public void reApply(String taskId, String carPackageAuditId) {
        //1.根据任务ID查询任务对象
        Task task = processService.getTaskByTaskId(taskId);
        //2.重新设置流程变量
        CarPackageAudit carPackageAudit = carPackageAuditMapper.getCarPackageAudit(carPackageAuditId);
        ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(),ServiceItem.class);
        processService.setVariable(taskId,"money",serviceItem.getDiscountPrice().longValue());
        //3.领取任务并完成任务
        processService.claimAndComplateTask(task,ShiroUtils.getUserId().toString(),true,"重新申请");
        //4.完成任务后查询流程实例的下一个任务.
        Task nextTask = processService.getTaskByInstanceId(task.getProcessInstanceId());
        ProcessInstance instance = processService.getProcessInstanceById(task.getProcessInstanceId());
        //5.需要指定下一个任务的候选人
        List<String> auditors = new ArrayList<>();
        String taskDefinitionKey = nextTask.getTaskDefinitionKey();
        List<SysUser> auditorIdList = definitionNodeService.queryAuditorsByTaskDefinitionKey(taskDefinitionKey);
        for(SysUser auditor:auditorIdList){
            processService.addCandidateUser(nextTask.getId(),auditor.getUserId().toString());
            auditors.add(auditor.getUserName());
        }
        //6.更新审核对象CarPackageAudit
        carPackageAudit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        carPackageAudit.setAuditors(JSON.toJSONString(auditors));
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }


    @Override
    public List<CarPackageAudit> findDoneList(CarPackageAudit carPackageAudit) {
        long count = processService.selectDoneTaskCount(CarPackageAudit.DEFINITION_KEY,ShiroUtils.getUserId().toString());
        if(count>0){
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            List<HistoricTaskInstance> taskList = processService
                    .selectDoneTaskList(CarPackageAudit.DEFINITION_KEY,
                            ShiroUtils.getUserId().toString(),
                            (pageNum-1)*pageSize,
                            pageSize);
            //3.遍历待办任务,查询对应的CarPackAgeAudit
            List<CarPackageAudit> resultList = new ArrayList<>();
            CarPackageAudit audit;
            for (HistoricTaskInstance task : taskList) {
                HistoricProcessInstance historicProcessInstance = processService
                        .getHistoricProcessInstanceById(task.getProcessInstanceId());
                String businessKey = historicProcessInstance.getBusinessKey();
                audit = carPackageAuditMapper.getCarPackageAudit(businessKey);
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));
                audit.setTaskName(task.getName());
                audit.setDoneTime(task.getEndTime());
                audit.setTaskId(task.getId());
                resultList.add(audit);
            }
            Page<CarPackageAudit> list = new Page<>();
            list.setTotal(count);
            list.setPageNum(pageNum);
            list.setPageSize(pageSize);
            list.addAll(resultList);
            return list;
        }else{
            return Collections.emptyList();
        }
    }

@Override
public List<HistoricActivity> selectHistoryList(String instanceId) {
    //查询集合
    List<HistoricActivityInstance> instanceList = processService
            .selectHistoryTaskList(instanceId);
    List<HistoricActivity> resultList = new ArrayList<>();
    //遍历集合
    for (HistoricActivityInstance instance : instanceList) {
        HistoricActivity historicActivity = new HistoricActivity();
        //拷贝属性
        BeanUtils.copyProperties(instance, historicActivity);
        //查询审核批注
        historicActivity.setComment(processService.getTaskComment(instance.getTaskId()));
        String assignee = instance.getAssignee();
        if(StringUtils.isNotEmpty(assignee)){
            SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(assignee));
            if (sysUser != null) {
                //设置审核人姓名
                historicActivity.setAssigneeName(sysUser.getUserName());
            }
        }
        resultList.add(historicActivity);
    }
    return resultList;
}
}
